package com.alipay.rebate.shop.scheduler.orderimport;

import com.alibaba.fastjson.JSON;
import com.alipay.rebate.shop.constants.*;
import com.alipay.rebate.shop.dao.mapper.*;
import com.alipay.rebate.shop.helper.*;
import com.alipay.rebate.shop.model.*;
import com.alipay.rebate.shop.pojo.dingdanxia.QueryGoodsPromotioninfoRes;
import com.alipay.rebate.shop.pojo.dingdanxia.QueryGoodsPromotioninfoResponse;
import com.alipay.rebate.shop.pojo.jd.JdOrdersRsp;
import com.alipay.rebate.shop.pojo.jd.SkuInfo;
import com.alipay.rebate.shop.pojo.jd.TkJdOrdersResponse;
import com.alipay.rebate.shop.utils.DateUtil;
import com.alipay.rebate.shop.utils.DingdanxiaUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.IOException;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.temporal.TemporalAdjusters;
import java.util.Date;
import java.util.List;

@Component
public class JdOrdersImport extends AbstractJdAndPddOrdersImport {
    @Autowired
    JdOrdersMapper jdOrdersMapper;
    @Autowired
    TaskSettingsMapper taskSettingsMapper;
    @Autowired
    UserJdPidMapper userJdPidMapper;
    @Autowired
    UserIncomeMapper userIncomeMapper;
    @Autowired
    PddOrdersMapper pddOrdersMapper;
    @Autowired
    UserGradeMapper userGradeMapper;
    @Autowired
    UserMapper userMapper;
    @Autowired
    CommissionFreezeLevelSettingsMapper commissionFreezeLevelSettingsMapper;
    @Autowired
    CommissionLevelSettingsMapper commissionLevelSettingsMapper;
    @Resource
    UserIncomeHelper userIncomeHelper;
    @Resource
    IncomeCommissionFreezeLevelHelper incomeCommissionFreezeLevelHelper;
    @Autowired
    CouponGetRecordMapper couponGetRecordMapper;
    @Autowired
    InviteSettingsMapper inviteSettingsMapper;
    @Autowired
    OrdersMapper ordersMapper;

    private static final int FREEZE_TYPE = 2;

    private final SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    private Logger logger = LoggerFactory.getLogger(JdOrdersImport.class);

    @Transactional
    public void importJdOrders(String time, Integer pageNo, Integer pageSize, Integer type, Long childUnionId) throws IOException {
        JdOrdersRsp jdOrdersRsp = DingdanxiaUtil.getJdOrders(time, pageNo, pageSize, type, childUnionId);
        logger.debug("jdOrdersRsp is : {}",jdOrdersRsp);
        List<TkJdOrdersResponse> data = jdOrdersRsp.getData();
        if (data != null) {
            for (TkJdOrdersResponse ordersResponse : data) {

                //准备订单
                JdOrders jdOrders = buildJdOrders(ordersResponse);
                logger.debug("jdOrders is : {}", jdOrders);
                logger.debug("jdOrders pid is : {}", jdOrders.getPid());
                //处理订单
                dealWithJdOrders(jdOrders);
            }
        }
    }

    public void handleLastMonthCompletionStatusOrders(){

        LocalDate localDate = LocalDate.now();
        //上个月第一天
        LocalDate lastMonth = LocalDate.of(localDate.getYear(), localDate.getMonthValue() - 1, 1);
        //上个月的最后一天
        LocalDate lastDay = lastMonth.with(TemporalAdjusters.lastDayOfMonth());
        List<UserIncome> userIncomeList = userIncomeMapper.selectJdOrderUserIncomeByCreateTime(lastDay.toString());
        logger.debug("userIncomeList is : {}", userIncomeList);
        for (UserIncome userIncome : userIncomeList) {
            userIncome.setStatus(UserIncomeConstant.FREEZE);
            userIncomeMapper.updateUserIncomeByUserIncome(userIncome);
        }

    }

    private static BigDecimal getMaxMoneyRecord(List<UserIncome> userIncomeList){
        BigDecimal maxMoney = new BigDecimal("0.00");
        //找出最大金额的记录
        for (UserIncome userIncome : userIncomeList) {
            if (userIncome.getMoney().compareTo(maxMoney) >= 0){
                maxMoney = userIncome.getMoney();
            }
        }
        return maxMoney;
    }


    public void dealWithJdOrders(JdOrders jdOrders){

        //根据pid获取用户信息
        Long userId = userJdPidMapper.selectUserIdByPositionId(String.valueOf(jdOrders.getPositionId()));
        logger.debug("jdorders pid is : {}",jdOrders.getPositionId());
        logger.debug("userId is : {}",userId);
        if (userId == null){
            logger.debug("userId is null insert");
            jdOrders.setIsRecord(0);
            saveOrUpdateOrders(jdOrders);
            return;
        }
        jdOrders.setIsRecord(1);
        jdOrders.setUserId(userId);
        logger.debug("jd userId is : {}",userId);
        JdOrders preOrders = jdOrdersMapper.selectOrderByOrderId(jdOrders.getOrderId());
        if (preOrders == null){
            logger.debug("jdOrders is null");
            // 增加用户订单数
            countUserOrdersNum(jdOrders.getUserId());
            User user = userMapper.selectById(userId);
            jdOrders.setUserName(user.getUserNickName());
            // 根据不同的订单状态进行处理
            handleDifferentOrdersStatus(jdOrders,user,null);
            // 保存或更新订单
            saveOrUpdateOrders(jdOrders);
        }
        if (preOrders != null){
           checkOrderValidCode(userId,jdOrders,preOrders,null);
        }
    }

    private void checkOrderValidCode(Long userId,JdOrders jdOrders,JdOrders preOrders,String type){
        // 订单存在，并且订单状态一致，不进行处理
        if (jdOrders.getValidCode() == preOrders.getValidCode()){
            logger.debug("validCode equals");
            return;
        }
        User user = userMapper.selectById(userId);
        // 付款到成功状态
        if (preOrders.getValidCode() == JdOrdersConstant.JD_PAID_STATUS &&
                jdOrders.getValidCode() == JdOrdersConstant.JD_SUCCESS_STATUS){
            logger.debug("validCode paid ~ success");
            createOrUpdateIncomeRecord(jdOrders,user,null,null);
            saveOrUpdateOrders(jdOrders);
            return;
        }
        // 付款到失效状态
        if (paidToOverDueOrSuccessToOverDue(preOrders,jdOrders)){
            logger.debug("validCode paid ~ overDue");
            saveOrUpdateOrders(jdOrders);
            handleOverDueOrders(jdOrders.getOrderId().toString());
            return;
        }
    }

    // 根据订单状态来计算用户的佣金
    private void handleDifferentOrdersStatus(JdOrders orders, User user,String type){
        // 付款订单
        if (JdOrdersConstant.JD_PAID_STATUS.equals(orders.getValidCode()) ||
                JdOrdersConstant.JD_SUCCESS_STATUS.equals(orders.getValidCode())){
            // 计算用户佣金，上级，上上级
            countCommission(orders,user,1,orders.getEstimateFee(),orders.getPrice());
            // 获取冻结配置
            CommissionFreezeLevelSettings freezeSettingsByMoney = getFreezeSettingsByMoney(orders.getUserCommission(),FREEZE_TYPE);
            // 创建收益记录
            createOrUpdateIncomeRecord(orders,user,freezeSettingsByMoney,type);
        }

        //无效订单
        if (overDueStatusOrders(orders)){
            handleOverDueOrders(orders.getOrderId().toString());
        }
    }

    private void plusUserIntgeralTreasure(JdOrders orders,CommissionFreezeLevelSettings freezeSettingsByMoney,User user){
        if (freezeSettingsByMoney == null) {
            plusUserUit(orders.getUserUit(), orders.getOneLevelUserUit(), orders.getTwoLevelUserUit(), user);
        }
        if (freezeSettingsByMoney != null){
            if (freezeSettingsByMoney.getFreezeDay() == 0){
                plusUserUit(orders.getUserUit(), orders.getOneLevelUserUit(), orders.getTwoLevelUserUit(), user);
            }
        }
    }

    private boolean checkTheOrdersOfLastMonth(JdOrders orders){
        if (JdOrdersConstant.JD_ACCOUNTING_STATUS.equals(orders.getValidCode())){
            String orderTime = orders.getOrderTime();
            if (compareDate(orderTime)) {
                logger.debug("compareDate(orderTime) is : {}", compareDate(orderTime));
                logger.debug("orders have handle");
                return true;
            }
        }
        return false;
    }

    private void checkIsFirstBatchOrders(User user,JdOrders orders){
        //检查是否是第一笔完成的订单
        Long jdCount = jdOrdersMapper.selectCountByUserId(user.getUserId());
        logger.debug("jdOrders is : {}", jdCount);
        Long count = ordersMapper.selectCountByUserId(user.getUserId());
        Long pddCount = pddOrdersMapper.selectCountByUserId(user.getUserId());
        if (jdCount < 1 && count < 1 && pddCount < 1) {
            // 进入新人奖励
            checkNewUser(user.getUserId(), orders.getValidCode());
            if (user.getParentUserId() != null) {
                // 拉新奖励
                Long awardNum = checkAndAwardToUser(user, orders.getPrice());
                // 插入拉新收益明细
                insertJdOrdersPullNewUserIncome(orders, awardNum, user);
            }
        }
    }


    private boolean compareDate(String orderTime) {
        try {
            // 订单付款日期
            Date parse = null;
            parse = sdf.parse(orderTime);
            logger.debug("parse is : {}", parse);
            String lastMonthStartDay = DateUtil.getLastMonthStartDay();
            String lastMonthEndTime = DateUtil.getLastMonthEndTime();
            // 上个月开始与结算时间
            Date startTime = sdf.parse(lastMonthStartDay);
            Date endTime = sdf.parse(lastMonthEndTime);
            logger.debug("startTime is : {}", startTime);
            logger.debug("endTime is : {}", endTime);
            if (parse.compareTo(startTime) == 1 && parse.compareTo(endTime) == -1) {
                logger.debug("parse.compareTo(startTime) is : {}", parse.compareTo(startTime));
                logger.debug("parse.compareTo(endTime) : {}", parse.compareTo(endTime));

                // 订单为上个月的完成订单
                //算时间
                Date date = new Date();
                Date thisMonthTwentyDay = DateUtil.getThisMonthTwentyDay();
//            String s = "2020-08-21 00:00:00";
//            Date parse1 = sdf.parse(s);
                int result = date.compareTo(thisMonthTwentyDay);
                if (result == 1) {
                    // 当前日期为20号之前，则走正常处理逻辑
                    return false;
                }
                return true;
            }
        } catch (ParseException e) {
            logger.debug("" + e);
        }
        return false;
    }

    //创建收益记录
    private void createOrUpdateIncomeRecord(JdOrders orders, User user,
                                            CommissionFreezeLevelSettings freezeSettingsByMoney, String type){
        logger.debug("createIncomeRecord start");
        //查询订单是否已存在
        JdOrders jdOrders = jdOrdersMapper.selectOrderByOrderId(orders.getOrderId());
        if (jdOrders == null){
            insertUserIncome(orders,user,freezeSettingsByMoney);
        }else{
            // 查询数据库是否已经有用户记录
            List<UserIncome> userIncomeList = userIncomeMapper
                    .selectUserIncomeByOrdersId(jdOrders.getOrderId().toString());
            if (userIncomeList.size() > 0) {
                updateUserIncome(orders, user, userIncomeList, freezeSettingsByMoney,type);
            }else{
                insertUserIncome(orders,user,freezeSettingsByMoney);
            }
        }
        logger.debug("createIncomeRecord end");
    }

    private void insertUserIncome(
            JdOrders orders, User user,CommissionFreezeLevelSettings freezeCommissionSettings
    ){
        logger.debug("insertUserIncome start");
        BigDecimal userCommission = orders.getUserCommission();
        BigDecimal oneLevelCommission = orders.getOneLevelCommission();
        BigDecimal twoLevelCommission = orders.getTwoLevelCommission();
        // 往用户收益表插入记录
        // 1 购买用户本人
        Integer roadType = 0;
        insertUserIncome(orders,userCommission,user.getUserId(),freezeCommissionSettings,roadType);

        // 2 推广人，即上级用户
        if (user.getParentUserId() != null){
            roadType = 1;
            insertUserIncome(orders,oneLevelCommission,user.getParentUserId(),freezeCommissionSettings,roadType);
            User parentUser = userMapper.selectById(user.getParentUserId());
            if (parentUser.getParentUserId() != null){
                roadType = 2;
                insertUserIncome(orders,twoLevelCommission,parentUser.getParentUserId(),freezeCommissionSettings,roadType);
            }
        }
        logger.debug("insertUserIncome end");
    }

    private void insertUserIncome(
            JdOrders orders,
            BigDecimal money,
            Long userId,
            CommissionFreezeLevelSettings freezeCommissionSettings,
            Integer roadType
    ){
        boolean freezeCommission = false;
        if (freezeCommissionSettings != null){
            if (freezeCommissionSettings.getFreezeDay() != 0){
                logger.debug("freezeCommission");
                freezeCommission = true;
            }
        }
        UserIncome userIncome = userIncomeHelper.insertJdOrderCommissionIncome(orders,money,userId,roadType,freezeCommission);
        if(freezeCommissionSettings != null){
            incomeCommissionFreezeLevelHelper.insert(userIncome.getUserIncomeId(),
                    freezeCommissionSettings.getId());
        }
    }

    protected void updateUserIncome(
            JdOrders orders,
            User user,
            List<UserIncome> userIncomeList,
            CommissionFreezeLevelSettings freezeCommissionSettings,String type
    ){
        logger.debug("updateUserIncome start");
        BigDecimal userCommission = orders.getUserCommission();
        BigDecimal oneLevelCommission = orders.getOneLevelCommission();
        BigDecimal twoLevelCommission = orders.getTwoLevelCommission();
        // 往用户收益表插入记录
        // 1 购买用户本人
        UserIncome userIncome = getUserIncomeIdFromList(userIncomeList,user.getUserId());
        updateUserIncome(userIncome,userCommission,orders.getValidCode().longValue(),freezeCommissionSettings,type);

        // 2 推广人，即上级用户
        if (user.getParentUserId() != null){
            UserIncome parentIncome = getUserIncomeIdFromList(userIncomeList,user.getParentUserId());
            updateUserIncome(parentIncome,oneLevelCommission,orders.getValidCode().longValue(),freezeCommissionSettings,type);
            User parentUser = userMapper.selectById(user.getParentUserId());
            if (parentUser.getParentUserId() != null){
                UserIncome income = getUserIncomeIdFromList(userIncomeList,parentUser.getParentUserId());
                updateUserIncome(income,twoLevelCommission,orders.getValidCode().longValue(),freezeCommissionSettings,type);
            }
        }
        logger.debug("updateUserIncome end");
    }
    private void updateUserIncome(
            UserIncome preIncome, BigDecimal money, Long tkStatus,
            CommissionFreezeLevelSettings freezeCommissionSettings,String type
    ){
        UserIncome userIncome = new UserIncome();
        userIncome.setUserIncomeId(preIncome.getUserIncomeId());
        userIncome.setMoney(money);
        userIncome.setTkStatus(tkStatus);
        userIncome.setStatus(0);
        if (tkStatus.intValue()==JdOrdersConstant.JD_ACCOUNTING_STATUS
          || (tkStatus.intValue()==JdOrdersConstant.JD_SUCCESS_STATUS && type != null)
        ){
            if(freezeCommissionSettings == null ){
                userIncome.setStatus(UserIncomeConstant.IS_PAID);
            } else {
                userIncome.setStatus(getIncomeStatusWhenUpdate(preIncome,JdOrdersConstant.JD_ACCOUNTING_STATUS));
            }
            if (freezeCommissionSettings != null){
                if (freezeCommissionSettings.getFreezeDay() == 0){
                    userIncome.setStatus(UserIncomeConstant.IS_PAID);
                }
            }
        }
        userIncome.setUpdateTime(DateUtil.getNowStr());
        logger.debug("update UserIncome is: {}",userIncome);
        userIncomeMapper.updateUserIncomeByUserIncome(userIncome);
    }

    //判断订单是否已经存在
    private void saveOrUpdateOrders(JdOrders orders) {

        JdOrders jdOrders = jdOrdersMapper.selectOrderByOrderId(orders.getOrderId());
        logger.debug("jdOrders is : {}", jdOrders);
        //数据库没有此订单
        if (jdOrders == null) {
            logger.debug("insert pddOrders");
            jdOrdersMapper.insert(orders);
        }else {
            logger.debug("update pddOrders");
            jdOrdersMapper.updateJdOrders(orders);
        }

    }
    //准备订单信息
    private JdOrders buildJdOrders(TkJdOrdersResponse ordersResponse) throws IOException {

        JdOrders order = new JdOrders();

        logger.debug("ordersResponse.getFinishTime() is : {}",ordersResponse.getFinishTime());

        if (ordersResponse.getFinishTime() != 0) {
            order.setFinishTime(sdf.format(ordersResponse.getFinishTime()));
        }
        order.setOrderEmt(ordersResponse.getOrderEmt());
        order.setOrderId(ordersResponse.getOrderId());
        order.setOrderTime(sdf.format(ordersResponse.getOrderTime()));
        order.setParentId(ordersResponse.getParentId());
        order.setPayMonth(ordersResponse.getPayMonth());
        order.setPlus(ordersResponse.getPlus());
        order.setPopId(ordersResponse.getPopId());
        order.setUnionId(ordersResponse.getUnionId());
        order.setExt1(ordersResponse.getExt1());
        order.setValidCode(ordersResponse.getValidCode());
        List<SkuInfo> skuList = ordersResponse.getSkuList();
        for (SkuInfo skuInfo : skuList){
            Object queryGoodsPromotioninfo = DingdanxiaUtil.getQueryGoodsPromotioninfo(null, skuInfo.getSkuId().toString());
            String jsonString = JSON.toJSONString(queryGoodsPromotioninfo);
            QueryGoodsPromotioninfoRes queryGoodsPromotioninfoRes = gson.fromJson(jsonString, QueryGoodsPromotioninfoRes.class);
            List<QueryGoodsPromotioninfoResponse> data = queryGoodsPromotioninfoRes.getData();
            if (data != null) {
                for (QueryGoodsPromotioninfoResponse response : data) {
                    order.setImgUrl(response.getImgUrl());
                }
            }
            logger.debug("imgUrl is : {}",order.getImgUrl());
            order.setActualCosPrice(skuInfo.getActualCosPrice());
            order.setActualFee(skuInfo.getActualFee());
            order.setCommissionRate(skuInfo.getCommissionRate());
            order.setEstimateCosPrice(skuInfo.getEstimateCosPrice());
            order.setEstimateFee(skuInfo.getEstimateFee());
            order.setFinalRate(skuInfo.getFinalRate());
            order.setCid1(skuInfo.getCid1());
            order.setFrozenSkuNum(skuInfo.getFrozenSkuNum());
            order.setPid(skuInfo.getPid());
            order.setPositionId(skuInfo.getPositionId());
            order.setPrice(skuInfo.getPrice());
            order.setCid2(skuInfo.getCid2());
            order.setSiteId(skuInfo.getSiteId());
            order.setSkuId(skuInfo.getSkuId());
            order.setSkuName(skuInfo.getSkuName());
            order.setSkuNum(skuInfo.getSkuNum());
            order.setSkuReturnNum(skuInfo.getSkuReturnNum());
            order.setSubSideRate(skuInfo.getSubSideRate());
            order.setSubsidyRate(skuInfo.getSubsidyRate());
            order.setCid3(skuInfo.getCid3());
            order.setUnionAlias(skuInfo.getUnionAlias());
            order.setUnionTag(skuInfo.getUnionTag());
            order.setUnionTrafficGroup(skuInfo.getUnionTrafficGroup());
            order.setValidCode(skuInfo.getValidCode());
            order.setSubUnionId(skuInfo.getSubUnionId());
            order.setTraceType(skuInfo.getTraceType());
            order.setSkuinfoPayMonth(skuInfo.getPayMonth());
            order.setSkuinfoPopId(skuInfo.getPopId());
            order.setSkuinfoExt1(skuInfo.getExt1());
            order.setCpActid(skuInfo.getCpActId());
            order.setUnionRole(skuInfo.getUnionRole());
        }

        return order;
    }

    private Boolean overDueStatusOrders(JdOrders orders){
        return orders.getValidCode() == -1 || orders.getValidCode() == 2 || orders.getValidCode() == 3 || orders.getValidCode() == 4
                || orders.getValidCode() == 5 || orders.getValidCode() == 6 || orders.getValidCode() == 7 || orders.getValidCode() == 8
                || orders.getValidCode() == 9 || orders.getValidCode() == 10 || orders.getValidCode() == 11 || orders.getValidCode() == 12
                || orders.getValidCode() == 13 || orders.getValidCode() == 14;
    }

    private Boolean successToAccountOrPaidToAccount(JdOrders preJdOrders, JdOrders jdOrders){
        return (preJdOrders.getValidCode() == JdOrdersConstant.JD_PAID_STATUS &&
                jdOrders.getValidCode() == JdOrdersConstant.JD_ACCOUNTING_STATUS)
                || (preJdOrders.getValidCode() == JdOrdersConstant.JD_SUCCESS_STATUS &&
                jdOrders.getValidCode() == JdOrdersConstant.JD_ACCOUNTING_STATUS);
    }

    private Boolean paidToOverDueOrSuccessToOverDue(JdOrders preJdOrders, JdOrders jdOrders){
        return  (preJdOrders.getValidCode() == JdOrdersConstant.JD_PAID_STATUS &&
                overDueStatusOrders(jdOrders))
                || (preJdOrders.getValidCode() == JdOrdersConstant.JD_SUCCESS_STATUS &&
                overDueStatusOrders(jdOrders));
    }
}
